package xyz.wbsite.zentao.sdk.execution;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import xyz.wbsite.zentao.sdk.Constant;
import xyz.wbsite.zentao.sdk.ZentaoInstance;
import xyz.wbsite.zentao.sdk.execution.ent.ZtExecution;
import xyz.wbsite.zentao.sdk.execution.req.ZtExecutionActivateRequest;
import xyz.wbsite.zentao.sdk.execution.req.ZtExecutionCloseRequest;
import xyz.wbsite.zentao.sdk.execution.req.ZtExecutionCreateRequest;
import xyz.wbsite.zentao.sdk.execution.req.ZtExecutionDeleteRequest;
import xyz.wbsite.zentao.sdk.execution.req.ZtExecutionStartRequest;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionActivateResponse;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionCloseResponse;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionCreateResponse;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionDeleteResponse;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionGetResponse;
import xyz.wbsite.zentao.sdk.execution.rsp.ZtExecutionStartResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * 执行/迭代服务
 *
 * @author wangbing
 * @version 0.0.1
 * @since 1.8
 */
public class ZtExecutionService {

    private ZentaoInstance zentaoInstance;

    public ZtExecutionService(ZentaoInstance zentaoInstance) {
        this.zentaoInstance = zentaoInstance;
    }

    /**
     * 创建执行
     */
    public ZtExecutionCreateResponse create(ZtExecutionCreateRequest projectCreateRequest) {
        ZtExecutionCreateResponse response = new ZtExecutionCreateResponse();
        try {
            String url = StrUtil.format("/execution-create-{}-0-0-productID=0,branchID=0.json", projectCreateRequest.getProject());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("project", projectCreateRequest.getProject());
            httpRequest.form("name", projectCreateRequest.getName());
            httpRequest.form("code", projectCreateRequest.getCode());
            httpRequest.form("begin", projectCreateRequest.getBegin());
            httpRequest.form("end", projectCreateRequest.getEnd());
            httpRequest.form("delta", projectCreateRequest.getDelta());
            httpRequest.form("days", projectCreateRequest.getDays());
            httpRequest.form("lifetime", projectCreateRequest.getLifetime());
            httpRequest.form("status", "wait");
            httpRequest.form("plans[][]", "");
            httpRequest.form("team", projectCreateRequest.getTeam());
            httpRequest.form("teams", projectCreateRequest.getTeams());
            httpRequest.form("PO", projectCreateRequest.getPo());
            httpRequest.form("QD", projectCreateRequest.getQd());
            httpRequest.form("PM", projectCreateRequest.getPm());
            httpRequest.form("RD", projectCreateRequest.getRd());
            for (String teamMember : projectCreateRequest.getTeamMembers()) {
                httpRequest.form("teamMembers[]", teamMember);
            }
            httpRequest.form("desc", projectCreateRequest.getDesc());
            httpRequest.form("acl", projectCreateRequest.getAcl());
            httpRequest.form("uid", RandomUtil.randomString(13));

            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            // 返回 {"result":"success","message":"保存成功","id":"366"}
            StaticLog.info(body);
            if (body.contains(Constant.SUCCESS_KEY)) {
                JSONObject entries = JSONUtil.parseObj(body);
                response.setId(Convert.toInt(entries.get("id")));
                response.setSuccess(true);
                response.setMessage("请求成功");
                return response;
            }
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 关闭执行
     */
    public ZtExecutionStartResponse start(ZtExecutionStartRequest projectStartRequest) {
        ZtExecutionStartResponse response = new ZtExecutionStartResponse();
        try {
            String url = StrUtil.format("/execution-start-{}.json", projectStartRequest.getExecutionId());
            StaticLog.info(url);
            HttpRequest request = zentaoInstance.createPost(url);
            request.form("status", "doing");
            request.form("realBegan", projectStartRequest.getRealBegan());
            request.form("comment", projectStartRequest.getComment());
            request.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = request.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            // 返回的是html
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 关闭执行
     */
    public ZtExecutionCloseResponse close(ZtExecutionCloseRequest projectCloseRequest) {
        ZtExecutionCloseResponse response = new ZtExecutionCloseResponse();
        try {
            String url = StrUtil.format("/execution-close-{}.html", projectCloseRequest.getExecutionId());
            StaticLog.info(url);
            HttpRequest request = zentaoInstance.createPost(url);
            request.form("status", "closed");
            request.form("realEnd", projectCloseRequest.getRealEnd());
            request.form("comment", projectCloseRequest.getComment());
            request.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = request.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            StaticLog.info(Convert.unicodeToStr(body));
            // 返回的是html
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 激活执行
     */
    public ZtExecutionActivateResponse activate(ZtExecutionActivateRequest projectActivateRequest) {
        ZtExecutionActivateResponse response = new ZtExecutionActivateResponse();
        try {
            String url = StrUtil.format("/execution-close-{}.html", projectActivateRequest.getExecutionId());
            StaticLog.info(url);
            HttpRequest request = zentaoInstance.createPost(url);
            request.form("begin", projectActivateRequest.getBegin());
            request.form("end", projectActivateRequest.getEnd());
            request.form("readjustTime", projectActivateRequest.getReadjustTime());
            request.form("status", "doing");
            request.form("comment", projectActivateRequest.getComment());
            request.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = request.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            StaticLog.info(Convert.unicodeToStr(body));
            // 返回的是html
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 激活执行
     */
    public ZtExecutionDeleteResponse delete(ZtExecutionDeleteRequest projectDeleteRequest) {
        ZtExecutionDeleteResponse response = new ZtExecutionDeleteResponse();
        try {
            String url = StrUtil.format("/execution-delete-{}.html", projectDeleteRequest.getExecutionId());
            StaticLog.info(url);
            HttpRequest request = zentaoInstance.createPost(url);
            HttpResponse execute = request.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            StaticLog.info(Convert.unicodeToStr(body));
            // 返回的是html
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 设置查询条件
     * <p>
     * 禅道查询条件是设置在session中的，所有查询之前先设置参数
     */
    private boolean setQuery(int projectId, String fieldName, String fieldValue) {
        try {
            String url = StrUtil.format("/search-buildQuery.html");
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("fieldname", "");
            httpRequest.form("fieldid", "");
            httpRequest.form("fieldstatus", "0");
            httpRequest.form("fieldproject", "0");
            httpRequest.form("fieldPM", "");
            httpRequest.form("fieldopenedBy", "");
            httpRequest.form("fieldopenedDate", "");
            httpRequest.form("fieldbegin", "");
            httpRequest.form("fieldend", "");
            httpRequest.form("fieldrealBegan", "");
            httpRequest.form("fieldrealEnd", "");
            httpRequest.form("fieldclosedBy", "");
            httpRequest.form("fieldlastEditedDate", "");
            httpRequest.form("fieldclosedDate", "");
            httpRequest.form("fieldteamCount", "");
            httpRequest.form("andOr1", "AND");
            httpRequest.form("field1", fieldName);
            httpRequest.form("operator1", "=");
            httpRequest.form("value1", fieldValue);
            httpRequest.form("andOr2", "and");
            httpRequest.form("field2", "id");
            httpRequest.form("operator2", "=");
            httpRequest.form("value2", "");
            httpRequest.form("andOr3", "and");
            httpRequest.form("field3", "status");
            httpRequest.form("operator3", "=");
            httpRequest.form("value3", "0");
            httpRequest.form("groupAndOr", "and");
            httpRequest.form("andOr4", "AND");
            httpRequest.form("field4", "project");
            httpRequest.form("operator4", "=");
            httpRequest.form("value4", projectId);
            httpRequest.form("andOr5", "and");
            httpRequest.form("field5", "PM");
            httpRequest.form("operator5", "=");
            httpRequest.form("value5", "");
            httpRequest.form("andOr6", "and");
            httpRequest.form("field6", "openedBy");
            httpRequest.form("operator6", "=");
            httpRequest.form("value6", "");
            httpRequest.form("module", "execution");
            httpRequest.form("actionURL", "/execution-all-bySearch-order_asc-0-myQueryID.html");
            httpRequest.form("groupItems", "3");
            httpRequest.form("formType", "lite");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                return false;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            return execute.getStatus() == HttpStatus.HTTP_OK;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        return false;
    }

    /**
     * 通过执行名称获取执行
     */
    public ZtExecutionGetResponse getByName(int projectId, String name) {
        ZtExecutionGetResponse response = new ZtExecutionGetResponse();
        try {
            boolean setQuery = setQuery(projectId, "name", name);
            if (!setQuery) {
                response.setSuccess(false);
                response.setMessage("设置查询参数失败");
                return response;
            }
            HttpRequest httpRequest = zentaoInstance.createGetForHtml("/execution-all-bySearch-order_asc-0-myQueryID.html");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            Document parse = Jsoup.parse(body);
            Elements trs = parse.select(".main-table .sortable tr");
            if (trs.size() == 1) {
                Element tr = trs.get(0);
                ZtExecution ztExecution = new ZtExecution();
                ztExecution.setId(Convert.toInt(tr.select(".c-id").text()));
                ztExecution.setName(tr.select(".c-name").attr("title"));
                ztExecution.setCode(tr.select(".c-code").attr("title"));
                ztExecution.setProjectId(projectId);
                ztExecution.setProjectName(tr.select(".c-project").attr("title"));
                ztExecution.setPm(tr.select(".c-PM").text());
                ztExecution.setStatus(tr.select(".c-status").text());
                ztExecution.setProgress(tr.select(".c-progress").text());
                ztExecution.setBegin(tr.select(".c-begin").text());
                ztExecution.setEnd(tr.select(".c-end").text());
                ztExecution.setEstimate(tr.select(".c-estimate").text());
                ztExecution.setConsumed(tr.select(".c-consumed").text());
                ztExecution.setLeft(tr.select(".c-left").text());
                response.setSuccess(true);
                response.setMessage("请求成功");
                response.setResult(ztExecution);
                return response;
            }
            StaticLog.info(body);
            response.setMessage("无数据");
            return response;
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 通过项目编码获取项目
     */
    public ZtExecutionGetResponse getByCode(int projectId, String code) {
        ZtExecutionGetResponse response = new ZtExecutionGetResponse();
        try {
            boolean setQuery = setQuery(projectId, "code", code);
            if (!setQuery) {
                response.setSuccess(false);
                response.setMessage("设置查询参数失败");
                return response;
            }
            HttpRequest httpRequest = zentaoInstance.createGetForHtml("/execution-all-bySearch-order_asc-0-myQueryID.html");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            Document parse = Jsoup.parse(body);
            Elements trs = parse.select(".main-table .sortable tr");
            if (trs.size() == 1) {
                Element tr = trs.get(0);
                ZtExecution ztExecution = new ZtExecution();
                ztExecution.setId(Convert.toInt(tr.select(".c-id").text()));
                ztExecution.setName(tr.select(".c-name").attr("title"));
                ztExecution.setCode(tr.select(".c-code").attr("title"));
                ztExecution.setProjectId(projectId);
                ztExecution.setProjectName(tr.select(".c-project").attr("title"));
                ztExecution.setPm(tr.select(".c-PM").text());
                ztExecution.setStatus(tr.select(".c-status").text());
                ztExecution.setProgress(tr.select(".c-progress").text());
                ztExecution.setBegin(tr.select(".c-begin").text());
                ztExecution.setEnd(tr.select(".c-end").text());
                ztExecution.setEstimate(tr.select(".c-estimate").text());
                ztExecution.setConsumed(tr.select(".c-consumed").text());
                ztExecution.setLeft(tr.select(".c-left").text());
                response.setSuccess(true);
                response.setMessage("请求成功");
                response.setResult(ztExecution);
                return response;
            }
            StaticLog.info(body);
            response.setMessage("无数据");
            return response;
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }
}
